extensions/simple: implement some 32bit integer fast paths
authorØyvind Kolås <pippin@gimp.org>
Fri, 9 Dec 2016 19:07:47 +0000 (20:07 +0100)
committerØyvind Kolås <pippin@gimp.org>
Fri, 9 Dec 2016 21:02:05 +0000 (22:02 +0100)
extensions/simple.c

index bde77854cb3dec69d8f154d400029c602a8399cb..475592165367f0307d68e87820e72874ae1b04cb 100644 (file)
@@ -113,6 +113,91 @@ float_pre_to_u16_pre (unsigned char *src_char, unsigned char *dst_char, long sam
   return samples;
 }
 
+static inline long
+float_pre_to_u32_pre (unsigned char *src_char, unsigned char *dst_char, long samples)
+{
+  float *src = (float *)src_char;
+  uint32_t *dst = (uint32_t *)dst_char;
+  long n = samples;
+  while (n--)
+    {
+      float r = src[0];
+      float g = src[1];
+      float b = src[2];
+      float a = src[3];
+      
+      if (a > 1.0f) {
+        r /= a;
+        g /= a;
+        b /= a;
+        a /= a;
+      }
+      
+      dst[0] = (r >= 1.0f) ? 0xFFFFFFFF : ((r <= 0.0f) ? 0x0 : 0xFFFFFFFF * r + 0.5f);
+      dst[1] = (g >= 1.0f) ? 0xFFFFFFFF : ((g <= 0.0f) ? 0x0 : 0xFFFFFFFF * g + 0.5f);
+      dst[2] = (b >= 1.0f) ? 0xFFFFFFFF : ((b <= 0.0f) ? 0x0 : 0xFFFFFFFF * b + 0.5f);
+      dst[3] = (a >= 1.0f) ? 0xFFFFFFFF : ((a <= 0.0f) ? 0x0 : 0xFFFFFFFF * a + 0.5f);
+      
+      dst += 4;
+      src += 4;
+    }
+  return samples;
+}
+
+
+static inline long
+float_to_u32 (unsigned char *src_char, unsigned char *dst_char, long samples)
+{
+  float *src    = (float *)src_char;
+  uint32_t *dst = (uint32_t *)dst_char;
+  long n = samples;
+  while (n--)
+    {
+      float r = src[0];
+      float g = src[1];
+      float b = src[2];
+      float a = src[3];
+            
+      dst[0] = (r >= 1.0f) ? 0xFFFFFFFF : ((r <= 0.0f) ? 0x0 : 0xFFFFFFFF * r + 0.5f);
+      dst[1] = (g >= 1.0f) ? 0xFFFFFFFF : ((g <= 0.0f) ? 0x0 : 0xFFFFFFFF * g + 0.5f);
+      dst[2] = (b >= 1.0f) ? 0xFFFFFFFF : ((b <= 0.0f) ? 0x0 : 0xFFFFFFFF * b + 0.5f);
+      dst[3] = (a >= 1.0f) ? 0xFFFFFFFF : ((a <= 0.0f) ? 0x0 : 0xFFFFFFFF * a + 0.5f);
+      
+      dst += 4;
+      src += 4;
+    }
+  return samples;
+}
+
+static inline long
+u32_to_float (unsigned char *src_char, unsigned char *dst_char, long samples)
+{
+  uint32_t *src = (uint32_t *)src_char;
+  float *dst    = (float *)dst_char;
+  long n = samples;
+  while (n--)
+    {
+      dst[0] = src[0] / 4294967296.0f;
+      dst ++;
+      src ++;
+    }
+  return samples;
+}
+
+static inline long
+u32_to_float_x4 (unsigned char *src_char, unsigned char *dst_char, long samples)
+{
+  u32_to_float (src_char, dst_char, samples * 4);
+  return samples;
+}
+
+static inline long
+u32_to_float_x2 (unsigned char *src_char, unsigned char *dst_char, long samples)
+{
+  u32_to_float (src_char, dst_char, samples * 2);
+  return samples;
+}
+
 int
 init (void)
 {
@@ -160,5 +245,66 @@ init (void)
                        float_pre_to_u16_pre,
                        NULL);
 
+
+  /* float and u32 */
+  babl_conversion_new (babl_format ("R'G'B'A float"),
+                       babl_format ("R'G'B'A u32"),
+                      "linear", 
+                       float_to_u32,
+                       NULL);
+  babl_conversion_new (babl_format ("RGBA float"),
+                       babl_format ("RGBA u32"),
+                      "linear", 
+                       float_to_u32,
+                       NULL);
+  babl_conversion_new (babl_format ("R'aG'aB'aA float"),
+                       babl_format ("R'aG'aB'aA u32"),
+                      "linear", 
+                       float_pre_to_u32_pre,
+                       NULL);
+  babl_conversion_new (babl_format ("RaGaBaA float"),
+                       babl_format ("RaGaBaA u32"),
+                      "linear", 
+                       float_pre_to_u32_pre,
+                       NULL);
+
+
+  babl_conversion_new (babl_format ("YA u32"),
+                       babl_format ("YA float"),
+                      "linear", 
+                       u32_to_float_x2,
+                       NULL);
+
+  babl_conversion_new (babl_format ("Y'A u32"),
+                       babl_format ("Y'A float"),
+                      "linear", 
+                       u32_to_float_x2,
+                       NULL);
+
+  babl_conversion_new (babl_format ("Y u32"),
+                       babl_format ("Y float"),
+                      "linear", 
+                       u32_to_float,
+                       NULL);
+
+  babl_conversion_new (babl_format ("Y' u32"),
+                       babl_format ("Y' float"),
+                      "linear", 
+                       u32_to_float,
+                       NULL);
+
+  babl_conversion_new (babl_format ("RGBA u32"),
+                       babl_format ("RGBA float"),
+                      "linear", 
+                       u32_to_float_x4,
+                       NULL);
+
+  babl_conversion_new (babl_format ("R'G'B'A u32"),
+                       babl_format ("R'G'B'A float"),
+                      "linear", 
+                       u32_to_float_x4,
+                       NULL);
+
+
   return 0;
 }